import type { ICourseState } from './courseStore';
import { CourseStatusEnum, CourseCategoryStatusEnum } from '@/types/course/enums';
import type { ICourse } from '@/types/course/course';
import type { ICourseCategory } from '@/types/course/courseCategory';

/**
 * 课程选择器函数
 * @description 提供各种课程和分类数据的选择和计算函数
 */
export const courseSelectors = {
  // ==================== 课程相关选择器 ====================
  
  /**
   * 获取所有课程
   * @param state 课程状态
   * @returns 所有课程列表
   */
  getAllCourses: (state: ICourseState): ICourse[] => state.courses,

  /**
   * 获取正常状态的课程
   * @param state 课程状态
   * @returns 正常课程列表
   */
  getActiveCourses: (state: ICourseState): ICourse[] => 
    state.courses.filter(course => course.status === CourseStatusEnum.ACTIVE),

  /**
   * 获取暂停状态的课程
   * @param state 课程状态
   * @returns 暂停课程列表
   */
  getSuspendedCourses: (state: ICourseState): ICourse[] => 
    state.courses.filter(course => course.status === CourseStatusEnum.SUSPENDED),

  /**
   * 根据ID获取课程
   * @param state 课程状态
   * @param id 课程ID
   * @returns 课程信息或undefined
   */
  getCourseById: (state: ICourseState, id: string): ICourse | undefined => 
    state.courses.find(course => course.id === id),

  /**
   * 根据课程代码获取课程
   * @param state 课程状态
   * @param courseCode 课程代码
   * @returns 课程信息或undefined
   */
  getCourseByCourseCode: (state: ICourseState, courseCode: string): ICourse | undefined => 
    state.courses.find(course => course.courseCode === courseCode),

  /**
   * 根据教师获取课程
   * @param state 课程状态
   * @param teacher 教师姓名
   * @returns 该教师的课程列表
   */
  getCoursesByTeacher: (state: ICourseState, teacher: string): ICourse[] => 
    state.courses.filter(course => course.teacher === teacher),

  /**
   * 根据分类获取课程
   * @param state 课程状态
   * @param categoryId 分类ID
   * @returns 该分类的课程列表
   */
  getCoursesByCategory: (state: ICourseState, categoryId: string): ICourse[] => 
    state.courses.filter(course => course.categoryIds.includes(categoryId)),

  /**
   * 根据难度等级获取课程
   * @param state 课程状态
   * @param level 难度等级
   * @returns 该难度等级的课程列表
   */
  getCoursesByLevel: (state: ICourseState, level: 'beginner' | 'intermediate' | 'advanced'): ICourse[] => 
    state.courses.filter(course => course.level === level),

  /**
   * 根据标签获取课程
   * @param state 课程状态
   * @param tag 标签
   * @returns 包含该标签的课程列表
   */
  getCoursesByTag: (state: ICourseState, tag: string): ICourse[] => 
    state.courses.filter(course => course.tags && course.tags.includes(tag)),

  /**
   * 获取筛选后的课程列表
   * @param state 课程状态
   * @returns 筛选后的课程列表
   */
  getFilteredCourses: (state: ICourseState): ICourse[] => {
    let filtered = state.courses;

    // 应用筛选条件
    if (state.courseFilters.filters.categoryId) {
      filtered = filtered.filter(course => course.categoryIds.includes(state.courseFilters.filters.categoryId!));
    }

    if (state.courseFilters.filters.teacher) {
      filtered = filtered.filter(course => 
        course.teacher.toLowerCase().includes(state.courseFilters.filters.teacher!.toLowerCase())
      );
    }

    if (state.courseFilters.filters.status !== undefined) {
      filtered = filtered.filter(course => course.status === state.courseFilters.filters.status);
    }

    if (state.courseFilters.filters.level) {
      filtered = filtered.filter(course => course.level === state.courseFilters.filters.level);
    }

    if (state.courseFilters.filters.tags && state.courseFilters.filters.tags.length > 0) {
      filtered = filtered.filter(course => 
        course.tags && state.courseFilters.filters.tags!.some(tag => course.tags!.includes(tag))
      );
    }

    // 应用搜索关键词
    if (state.courseFilters.searchKeyword) {
      const keyword = state.courseFilters.searchKeyword.toLowerCase();
      filtered = filtered.filter(course => 
        course.name.toLowerCase().includes(keyword) ||
        course.courseCode.toLowerCase().includes(keyword) ||
        course.teacher.toLowerCase().includes(keyword) ||
        (course.description && course.description.toLowerCase().includes(keyword)) ||
        (course.tags && course.tags.some(tag => tag.toLowerCase().includes(keyword)))
      );
    }

    // 应用排序
    if (state.courseFilters.sortBy) {
      filtered.sort((a, b) => {
        const aValue = a[state.courseFilters.sortBy as keyof ICourse] as string;
        const bValue = b[state.courseFilters.sortBy as keyof ICourse] as string;
        
        if (!aValue && !bValue) return 0;
        if (!aValue) return 1;
        if (!bValue) return -1;
        
        const comparison = aValue.localeCompare(bValue);
        return state.courseFilters.sortOrder === 'asc' ? comparison : -comparison;
      });
    }

    return filtered;
  },

  /**
   * 获取选中的课程列表
   * @param state 课程状态
   * @returns 选中的课程列表
   */
  getSelectedCourses: (state: ICourseState): ICourse[] => 
    state.courses.filter(course => state.selectedCourseIds.includes(course.id)),

  /**
   * 获取所有教师列表
   * @param state 课程状态
   * @returns 教师列表（去重）
   */
  getAllTeachers: (state: ICourseState): string[] => {
    const teachers = state.courses.map(course => course.teacher);
    return Array.from(new Set(teachers)).sort();
  },

  /**
   * 获取所有标签列表
   * @param state 课程状态
   * @returns 标签列表（去重）
   */
  getAllTags: (state: ICourseState): string[] => {
    const tags = state.courses.flatMap(course => course.tags || []);
    return Array.from(new Set(tags)).sort();
  },

  /**
   * 获取课程统计信息
   * @param state 课程状态
   * @returns 统计信息
   */
  getCourseStatistics: (state: ICourseState) => {
    const courses = state.courses;
    const totalCount = courses.length;
    const activeCount = courses.filter(c => c.status === CourseStatusEnum.ACTIVE).length;
    const suspendedCount = courses.filter(c => c.status === CourseStatusEnum.SUSPENDED).length;

    // 教师分布
    const teacherMap = new Map<string, number>();
    courses.forEach(course => {
      teacherMap.set(course.teacher, (teacherMap.get(course.teacher) || 0) + 1);
    });
    const teacherDistribution = Array.from(teacherMap.entries()).map(([teacher, count]) => ({
      teacher,
      count
    }));

    // 难度等级分布
    const levelMap = new Map<'beginner' | 'intermediate' | 'advanced', number>();
    courses.forEach(course => {
      if (course.level) {
        levelMap.set(course.level, (levelMap.get(course.level) || 0) + 1);
      }
    });
    const levelDistribution = Array.from(levelMap.entries()).map(([level, count]) => ({
      level,
      count
    }));

    // 平均费用和时长
    const coursesWithFee = courses.filter(c => c.fee && c.fee > 0);
    const averageFee = coursesWithFee.length > 0 
      ? coursesWithFee.reduce((sum, c) => sum + (c.fee || 0), 0) / coursesWithFee.length 
      : 0;

    const coursesWithDuration = courses.filter(c => c.duration && c.duration > 0);
    const averageDuration = coursesWithDuration.length > 0 
      ? coursesWithDuration.reduce((sum, c) => sum + (c.duration || 0), 0) / coursesWithDuration.length 
      : 0;

    return {
      totalCount,
      activeCount,
      suspendedCount,
      teacherDistribution,
      levelDistribution,
      averageFee,
      averageDuration
    };
  },

  // ==================== 分类相关选择器 ====================

  /**
   * 获取所有分类
   * @param state 课程状态
   * @returns 所有分类列表
   */
  getAllCategories: (state: ICourseState): ICourseCategory[] => state.categories,

  /**
   * 获取正常状态的分类
   * @param state 课程状态
   * @returns 正常分类列表
   */
  getActiveCategories: (state: ICourseState): ICourseCategory[] => 
    state.categories.filter(category => category.status === CourseCategoryStatusEnum.ACTIVE),

  /**
   * 获取预设分类
   * @param state 课程状态
   * @returns 预设分类列表
   */
  getPresetCategories: (state: ICourseState): ICourseCategory[] => 
    state.categories.filter(category => category.isPreset),

  /**
   * 获取自定义分类
   * @param state 课程状态
   * @returns 自定义分类列表
   */
  getCustomCategories: (state: ICourseState): ICourseCategory[] => 
    state.categories.filter(category => !category.isPreset),

  /**
   * 根据ID获取分类
   * @param state 课程状态
   * @param id 分类ID
   * @returns 分类信息或undefined
   */
  getCategoryById: (state: ICourseState, id: string): ICourseCategory | undefined => 
    state.categories.find(category => category.id === id),

  /**
   * 根据分类代码获取分类
   * @param state 课程状态
   * @param categoryCode 分类代码
   * @returns 分类信息或undefined
   */
  getCategoryByCategoryCode: (state: ICourseState, categoryCode: string): ICourseCategory | undefined => 
    state.categories.find(category => category.categoryCode === categoryCode),

  /**
   * 根据父分类获取子分类
   * @param state 课程状态
   * @param parentId 父分类ID
   * @returns 子分类列表
   */
  getCategoriesByParent: (state: ICourseState, parentId?: string): ICourseCategory[] => 
    state.categories.filter(category => category.parentId === parentId),

  /**
   * 根据层级获取分类
   * @param state 课程状态
   * @param level 层级
   * @returns 该层级的分类列表
   */
  getCategoriesByLevel: (state: ICourseState, level: number): ICourseCategory[] => 
    state.categories.filter(category => category.level === level),

  /**
   * 获取筛选后的分类列表
   * @param state 课程状态
   * @returns 筛选后的分类列表
   */
  getFilteredCategories: (state: ICourseState): ICourseCategory[] => {
    let filtered = state.categories;

    // 应用筛选条件
    if (state.categoryFilters.filters.parentId !== undefined) {
      filtered = filtered.filter(category => category.parentId === state.categoryFilters.filters.parentId);
    }

    if (state.categoryFilters.filters.status !== undefined) {
      filtered = filtered.filter(category => category.status === state.categoryFilters.filters.status);
    }

    if (state.categoryFilters.filters.isPreset !== undefined) {
      filtered = filtered.filter(category => category.isPreset === state.categoryFilters.filters.isPreset);
    }

    // 应用搜索关键词
    if (state.categoryFilters.searchKeyword) {
      const keyword = state.categoryFilters.searchKeyword.toLowerCase();
      filtered = filtered.filter(category => 
        category.name.toLowerCase().includes(keyword) ||
        category.categoryCode.toLowerCase().includes(keyword) ||
        (category.description && category.description.toLowerCase().includes(keyword))
      );
    }

    // 应用排序
    if (state.categoryFilters.sortBy) {
      filtered.sort((a, b) => {
        if (state.categoryFilters.sortBy === 'sortOrder') {
          return state.categoryFilters.sortOrder === 'asc' 
            ? a.sortOrder - b.sortOrder 
            : b.sortOrder - a.sortOrder;
        }
        
        const aValue = a[state.categoryFilters.sortBy as keyof ICourseCategory] as string;
        const bValue = b[state.categoryFilters.sortBy as keyof ICourseCategory] as string;
        
        if (!aValue && !bValue) return 0;
        if (!aValue) return 1;
        if (!bValue) return -1;
        
        const comparison = aValue.localeCompare(bValue);
        return state.categoryFilters.sortOrder === 'asc' ? comparison : -comparison;
      });
    }

    return filtered;
  },

  /**
   * 获取分类树结构
   * @param state 课程状态
   * @returns 分类树结构
   */
  getCategoryTree: (state: ICourseState) => state.categoryTree,

  /**
   * 获取分类统计信息
   * @param state 课程状态
   * @returns 统计信息
   */
  getCategoryStatistics: (state: ICourseState) => {
    const categories = state.categories;
    const totalCount = categories.length;
    const activeCount = categories.filter(c => c.status === CourseCategoryStatusEnum.ACTIVE).length;
    const disabledCount = categories.filter(c => c.status === CourseCategoryStatusEnum.DISABLED).length;
    const presetCount = categories.filter(c => c.isPreset).length;
    const customCount = categories.filter(c => !c.isPreset).length;

    // 层级分布
    const levelMap = new Map<number, number>();
    categories.forEach(category => {
      levelMap.set(category.level, (levelMap.get(category.level) || 0) + 1);
    });
    const levelDistribution = Array.from(levelMap.entries()).map(([level, count]) => ({
      level,
      count
    }));

    return {
      totalCount,
      activeCount,
      disabledCount,
      presetCount,
      customCount,
      levelDistribution
    };
  },

  // ==================== 通用选择器 ====================

  /**
   * 检查课程是否有加载中的操作
   * @param state 课程状态
   * @returns 是否正在加载
   */
  isCourseLoading: (state: ICourseState): boolean => state.courseAsync.loading,

  /**
   * 检查分类是否有加载中的操作
   * @param state 课程状态
   * @returns 是否正在加载
   */
  isCategoryLoading: (state: ICourseState): boolean => state.categoryAsync.loading,

  /**
   * 获取课程错误信息
   * @param state 课程状态
   * @returns 错误信息
   */
  getCourseError: (state: ICourseState): string | null => state.courseAsync.error,

  /**
   * 获取分类错误信息
   * @param state 课程状态
   * @returns 错误信息
   */
  getCategoryError: (state: ICourseState): string | null => state.categoryAsync.error,

  /**
   * 获取课程最后更新时间
   * @param state 课程状态
   * @returns 最后更新时间戳
   */
  getCourseLastUpdated: (state: ICourseState): number | null => state.courseAsync.lastUpdated,

  /**
   * 获取分类最后更新时间
   * @param state 课程状态
   * @returns 最后更新时间戳
   */
  getCategoryLastUpdated: (state: ICourseState): number | null => state.categoryAsync.lastUpdated,

  /**
   * 检查是否有选中的课程
   * @param state 课程状态
   * @returns 是否有选中的课程
   */
  hasSelectedCourses: (state: ICourseState): boolean => state.selectedCourseIds.length > 0,

  /**
   * 检查课程是否全选
   * @param state 课程状态
   * @returns 是否全选
   */
  isAllCoursesSelected: (state: ICourseState): boolean => {
    const filteredCourses = courseSelectors.getFilteredCourses(state);
    return filteredCourses.length > 0 && 
           filteredCourses.every(course => state.selectedCourseIds.includes(course.id));
  },

  /**
   * 检查课程是否部分选中
   * @param state 课程状态
   * @returns 是否部分选中
   */
  isCoursesIndeterminate: (state: ICourseState): boolean => {
    const filteredCourses = courseSelectors.getFilteredCourses(state);
    const selectedCount = filteredCourses.filter(course => 
      state.selectedCourseIds.includes(course.id)
    ).length;
    return selectedCount > 0 && selectedCount < filteredCourses.length;
  },

  /**
   * 获取选中课程数量
   * @param state 课程状态
   * @returns 选中课程数量
   */
  getSelectedCourseCount: (state: ICourseState): number => state.selectedCourseIds.length,

  /**
   * 检查课程是否被选中
   * @param state 课程状态
   * @param courseId 课程ID
   * @returns 是否被选中
   */
  isCourseSelected: (state: ICourseState, courseId: string): boolean => 
    state.selectedCourseIds.includes(courseId)
};